﻿using AutoMapper;
using FreeSql;
using Microsoft.AspNetCore.Authentication.JwtBearer;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.StaticFiles;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.FileProviders;
using Microsoft.Extensions.Logging;
using Microsoft.IdentityModel.Tokens;
using Newtonsoft.Json;
using ProjectManageSystemApi.Services;
using ProjectManageSystemApi.Services.Impl;
using ProjectManageSystemApi.Utilities;
using System;
using System.Collections.Generic;
using System.IO;
using System.Text;
using System.Threading;

namespace ProjectManageSystemApi
{
    public class Startup
    {
        internal IConfiguration Configuration { get; }
        private readonly Config config;
        public IFreeSql Fsql { get; }

        public Startup(IConfiguration configuration)
        {
            Configuration = configuration;
            Fsql = new FreeSqlBuilder()
                    .UseConnectionString(DataType.MySql, Configuration.GetConnectionString("MySql"))
                    .Build();
            Fsql.Aop.CurdAfter += (s, e) => Console.WriteLine($"{Thread.CurrentThread.ManagedThreadId}: {e.EntityType.FullName} {e.ElapsedMilliseconds} ms, \r\n{e.Sql}");
            config = new Config(Configuration);
        }
        public void ConfigureServices(IServiceCollection services)
        {
            services.AddCors(options =>
            {
                options.AddPolicy("cors", builder => builder.SetIsOriginAllowed(_ => true).AllowAnyMethod().AllowAnyHeader().AllowCredentials());                
            });
            services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme)
                .AddJwtBearer(options =>
                {
                    options.TokenValidationParameters = new TokenValidationParameters
                    {
                        ValidateIssuer = true,
                        ValidateAudience = true,
                        ValidateLifetime = true,
                        ClockSkew = TimeSpan.FromSeconds(config.Expires),
                        ValidateIssuerSigningKey = true,
                        ValidAudience = config.Audience,
                        ValidIssuer = config.Issuer,
                        IssuerSigningKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(config.SecurityKey))
                    };
                });

            services.AddMvc(options => 
            {
                options.EnableEndpointRouting = false;
                options.Filters.Add<ExceptionFilter>();
            })
            .SetCompatibilityVersion(CompatibilityVersion.Latest)
            .AddJsonOptions(options =>
            {
                //options.SerializerSettings.NullValueHandling = NullValueHandling.Ignore;
                options.JsonSerializerOptions.NumberHandling = (System.Text.Json.Serialization.JsonNumberHandling)NullValueHandling.Ignore;
            })
            .AddNewtonsoftJson();
            services.AddAutoMapper(typeof(AutoMapperProfie).Assembly);
            services.AddSwagger();
            services.AddSingleton<UniqueKeyTool>();
            services.AddSingleton(config);
            services.AddSingleton(Fsql);
            services.AddSingleton<IUserServices, UserServices>();
            services.AddSingleton<IRoleMenuServices, RoleMenuServices>(); 
            services.AddSingleton<ISupplierService, SupplierService>();
            services.AddSingleton<ISupplierGoodsService, SupplierGoodsService>();
            services.AddSingleton<IUploadServices, UploadServices>();
            services.AddSingleton<IUserCheckInfoService, UserCheckInfoService>();
            services.AddSingleton<IUploadServices, UploadServices>();
            services.AddSingleton<IProjectInfoServices, ProjectInfoServices>();
            services.AddSingleton<IRoleAuthServices, RoleAuthServices>();
            services.AddSingleton<IProjectUserInfoServices, ProjectUserInfoServices>();
            services.AddSingleton<IProjectItemInfoServices, ProjectItemInfoServices>();
            services.AddSingleton<IProjectItemImageInfoServices, ProjectItemImageInfoServices>();
            services.AddSingleton<ICostApplyService, CostApplyService>();
            services.AddSingleton<ICostApplyImageServices, CostApplyImageServices>();
            services.AddSingleton<ICostTypeServices, CostTypeServices>();
            services.AddSingleton<IUserPasswordServices, UserPasswordServices>();
            services.AddSingleton<IWorkerTypeInfoServices, WorkerTypeInfoServices>();
            services.AddSingleton<IUserCheckDetailServices, UserCheckDetailServices>();
            services.AddSingleton<IBuildingSiteBillServices, BuildingSiteBillServices>();
            services.AddSingleton<IBuildingSiteBillImagesServices, BuildingSiteBillImagesServices>();
            services.AddSingleton<IPreFinalAccountFileServices, PreFinalAccountFileServices>();
            services.AddSingleton<IProjectItemPriceRecordServices, ProjectItemPriceRecordServices>();
            services.AddSingleton<IPurchaseOrderServices, PurchaseOrderServices>();
            services.AddSingleton<ISystemServices, SystemServices>();
        }

        public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory)
        {
            if (env.IsDevelopment())
            {
                app.UseDeveloperExceptionPage();
            }
            else
            {
                app.UseHsts();
            }
            app.UseCors("cors");
            //var provider = new FileExtensionContentTypeProvider();
            //provider.Mappings.Remove(".jpg");
            app.UseStaticFiles(new StaticFileOptions
            {
                OnPrepareResponse = (c) =>
                {
                    c.Context.Response.Headers.Add("Access-Control-Allow-Origin", "*");
                },
                
                //ContentTypeProvider = provider
                //ServeUnknownFileTypes = true
                //ContentTypeProvider = new FileExtensionContentTypeProvider(new Dictionary<string, string>
                //{
                //    { ".apk","application/vnd.android.package-archive"},
                //    { ".nupkg","application/zip"}
                //})
            });

            ConfigureFileServer(app);


            app.UseHttpsRedirection();
            app.UseAuthentication();
            app.UseMvc();
            app.UseSwaggerUI();
        }

        private void ConfigureFileServer(IApplicationBuilder app)
        {
            // 用户考勤图片文件夹
            string userCheckInfoUploadPath = Path.Combine(config.PublicPath, config.UserCheckInfoUploadPath);
            if (!Directory.Exists(userCheckInfoUploadPath))
            {
                Directory.CreateDirectory(userCheckInfoUploadPath);
            }
            app.UseFileServer(new FileServerOptions
            {
                FileProvider = new PhysicalFileProvider(userCheckInfoUploadPath),
                RequestPath = "/api/" + config.UserCheckInfoUploadPath
            });

            // 用户报销图片文件夹
            string costInfoUploadPath = Path.Combine(config.PublicPath, config.CostInfoUploadPath);
            if (!Directory.Exists(costInfoUploadPath))
            {
                Directory.CreateDirectory(costInfoUploadPath);
            }
            app.UseFileServer(new FileServerOptions
            {
                FileProvider = new PhysicalFileProvider(costInfoUploadPath),
                RequestPath = "/api/" + config.CostInfoUploadPath
            });

            // 工程项目图片文件夹
            string projectItemInfoUploadPath = Path.Combine(config.PublicPath, config.ProjectItemInfoUploadPath);
            if (!Directory.Exists(projectItemInfoUploadPath))
            {
                Directory.CreateDirectory(projectItemInfoUploadPath);
            }
            app.UseFileServer(new FileServerOptions
            {
                FileProvider = new PhysicalFileProvider(projectItemInfoUploadPath),
                RequestPath = "/api/" + config.ProjectItemInfoUploadPath
            });

            // 工程单据图片文件夹
            string projectBillInfoUploadPath = Path.Combine(config.PublicPath, config.ProjectBillInfoUploadPath);
            if (!Directory.Exists(projectBillInfoUploadPath))
            {
                Directory.CreateDirectory(projectBillInfoUploadPath);
            }
            app.UseFileServer(new FileServerOptions
            {
                FileProvider = new PhysicalFileProvider(projectBillInfoUploadPath),
                RequestPath = "/api/" + config.ProjectBillInfoUploadPath
            });

            // 预决算管理文件夹
            string preFinalAccountFileUploadPath = Path.Combine(config.PublicPath, config.PreFinalAccountFileUploadPath);
            if (!Directory.Exists(preFinalAccountFileUploadPath))
            {
                Directory.CreateDirectory(preFinalAccountFileUploadPath);
            }
            app.UseFileServer(new FileServerOptions
            {
                FileProvider = new PhysicalFileProvider(preFinalAccountFileUploadPath),
                RequestPath = "/api/" + config.PreFinalAccountFileUploadPath
            });

            // App文件夹
            //string AppInfoPath = Path.Combine(config.PublicPath, config.AppInfoPath);
            //if (!Directory.Exists(AppInfoPath))
            //{
            //    Directory.CreateDirectory(AppInfoPath);
            //}
            //app.UseFileServer(new FileServerOptions
            //{
            //    FileProvider = new PhysicalFileProvider(AppInfoPath),
            //    RequestPath = "/api/" + config.AppInfoPath
            //});
        }
    }
}
